// cSpell:words jqxhr

/* global $ location FormData XMLHttpRequest*/

const {toastError, toastNormal, toastSuccess} = require("./toast")

exports.alertAjaxError = function(xhr) {
    toastError(exports.parseXhrErrorMessage(xhr))
    throw xhr
}

exports.alertAjaxIfError = function(q) {
    return q.catch(exports.alertAjaxError)
}

exports.parseXhrErrorMessage = function(xhr) {
    try {
        return xhr.responseText &&
            JSON.parse(xhr.responseText).message ||
            `${xhr.status}:${xhr.responseText}`
    } catch (e) {
        return `${xhr.status}:${xhr.responseText}`
    }
}

exports.getAbsolute = function(absoluteUrl, data, settings) {
    let q = $.ajax(absoluteUrl, new AjaxOption("GET", data, settings))
    return Promise.resolve(q).fail(failHandler)
}

exports.default = new Relative("/api/")

exports.main = new Relative("/api/pgc/")

exports.upload = function($file, callback) {
    let files = $file[0].files
    if (!(files && files.length)) return callback(false)

    function parseSuccessMessage(xhr) {
        let response = xhr.responseText && JSON.parse(xhr.responseText)
        let path = response.fileRelativePath
        let size = response.fileSize
        return {path, size}
    }

    let fileCount = files.length
    let resultList = []

    function onOneFileDone(index, result, data) {
        fileCount--
        if (result) resultList[index] = data
        if (fileCount === 0) callback(resultList)
    }

    function uploadOne(index, file) {
        let xhr = new XMLHttpRequest()
        xhr.open("POST", "/api/school/file")
        xhr.onload = function() {
            switch (xhr.status) {
            case 200:
                onOneFileDone(index, true, parseSuccessMessage(xhr))
                toastSuccess("上传成功！")
                break
            case 413:
                onOneFileDone(index, false)
                toastError("文件大小超过限制！")
                break
            default:
                onOneFileDone(index, false)
                toastError(`上传失败[${xhr.status}]。`)
            }
        }

        xhr.onerror = function(e) {
            console.log(e)
            onOneFileDone(index, false)
            toastError("上传失败，遇到错误！")
        }

        let data = new FormData()
        data.append("f0", file)
        xhr.send(data)
    }


    for (let i = 0 ;i < files.length; i++) {
        let file = files[i]
        uploadOne(i, file)
    }
}

function AjaxOption(type, data, settings) {
    this.type = type

    if (type === "POST" || type === "PUT" || type === "DELETE") {
        this.data = data && JSON.stringify(data)
        this.contentType = "application/json"
    } else {
        this.data = data
    }

    this.cache = false

    if (settings) Object.assign(this, settings)
}

function failHandler() {
    return function(jqxhr) {
        "use strict"
        if (jqxhr.status === 401) {
            let r = jqxhr.responseText && JSON.parse(jqxhr.responseText)
            let href = encodeURIComponent(location.href)
            toastNormal("准备验证用户身份...")
            let redirect = () => location.href = r.signInUrl + `?callback=${href}`
            setTimeout(redirect, 1500)
        }
    }
}

function Relative(apiRoot) {
    let ctx = {}

    ctx.get = function(relativeUrl, data, settings) {
        return Promise.resolve($.ajax(apiRoot + relativeUrl, new AjaxOption("GET", data, settings))
            .fail(failHandler(apiRoot, relativeUrl)))
    }

    ctx.post = function(relativeUrl, data, settings) {
        return Promise.resolve($.ajax(apiRoot + relativeUrl, new AjaxOption("POST", data, settings))
            .fail(failHandler(apiRoot, relativeUrl)))
    }

    ctx.put = function(relativeUrl, data) {
        return Promise.resolve($.ajax(apiRoot + relativeUrl, new AjaxOption("PUT", data))
            .fail(failHandler(apiRoot, relativeUrl)))
    }

    ctx.remove = function(relativeUrl, data) {
        return Promise.resolve($.ajax(apiRoot + relativeUrl, new AjaxOption("DELETE", data))
            .fail(failHandler(apiRoot, relativeUrl)))
    }

    return ctx
}

exports.uploadBlob = function(blob, callback, fileName) {
    function parseSuccessMessage(xhr) {
        let response = xhr.responseText && JSON.parse(xhr.responseText)
        let path = response.fileRelativePath
        let size = response.fileSize
        return {path, size}
    }

    let xhr = new XMLHttpRequest()
    xhr.open("POST", "/api/jc/file")
    xhr.onload = function() {
        switch (xhr.status) {
        case 200:
            callback(true, parseSuccessMessage(xhr))
            // toastSuccess("上传成功！")
            break
        case 413:
            callback(false)
            toastError("文件大小超过限制！")
            break
        default:
            callback(false)
            toastError(`上传失败[${xhr.status}]。`)
        }
    }

    xhr.onerror = function(e) {
        console.log(e)
        callback(false)
        toastError("上传失败，遇到错误！")
    }

    let data = new FormData()
    if (fileName) {
        data.append("f0", blob, fileName)
    } else {
        data.append("f0", blob)
    }
    xhr.send(data)
}
